using System;
using System.Collections;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace JTLeigh.Tools.Development.CopySourceAsHtml.UnitTests
{

    /// <summary>
    /// Unit tests for the <see cref="HtmlLine"/> class.
    /// </summary>
    [TestClass]
    public class HtmlLineFixture
    {
        #region Methods

        #region AddBlock

        /// <summary>
        /// Ensures <see cref="HtmlLine.AddBlock"/> correctly throws <see cref="ArgumentNullException"/>
        /// when called with a <see langword="null"/> block.
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestAddBlockWithNullBlock()
        {
            HtmlLine line;

            line = new HtmlLine();
            line.AddBlock(null);
        }

        /// <summary>
        /// Ensures <see cref="HtmlLine.AddBlock"/> adds the block to the line's list of blocks.
        /// </summary>
        [TestMethod]
        public void TestAddBlock()
        {
            HtmlLine line;
            HtmlBlock block;

            line = new HtmlLine();
            block = new HtmlBlock();
            line.AddBlock(block);

            Assert.AreEqual(1, line.Blocks.Count);
            Assert.AreSame(block, line.Blocks[0]);
        }

        #endregion // AddBlock

        #region HasContent

        /// <summary>
        /// Ensures <see cref="HtmlLine.HasContent"/> correctly determines whether the line has
        /// content based on whether its blocks have content.
        /// </summary>
        [TestMethod]
        public void TestHasContent()
        {
            HtmlLine line;
            HtmlBlock block;

            line = new HtmlLine();
            Assert.IsFalse(line.HasContent);

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.IsFalse(line.HasContent);

            block.Append(' ', 4);
            Assert.IsFalse(line.HasContent); // no content yet, only 1 block of leading spaces

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.IsFalse(line.HasContent);

            block.Append(' ', 4);
            Assert.IsFalse(line.HasContent); // no content yet, only 2 blocks of leading spaces

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.IsFalse(line.HasContent);

            block.Append(' ', 4);
            Assert.IsFalse(line.HasContent); // no content yet, only 3 blocks of leading spaces

            block.Append('!', 4);
            Assert.IsTrue(line.HasContent); // 3rd block has both leading spaces and content, so the line has content
        }

        #endregion // HasContent

        #region LeadingSpaces

        /// <summary>
        /// Ensures <see cref="HtmlLine.LeadingSpaces"/> correctly determines the number of leading 
        /// spaces the line has based on the number of leading spaces in its blocks.
        /// </summary>
        [TestMethod]
        public void TestLeadingSpaces()
        {
            HtmlLine line;
            HtmlBlock block;

            line = new HtmlLine();
            Assert.AreEqual(0, line.LeadingSpaces);

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.AreEqual(0, line.LeadingSpaces);

            block.Append(' ', 4);
            Assert.AreEqual(1, line.LeadingSpaces); // 1 leading space on 1 block

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.AreEqual(1, line.LeadingSpaces);

            block.Append(' ', 4);
            Assert.AreEqual(2, line.LeadingSpaces); // 2 leading spaces on 2 blocks

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.AreEqual(2, line.LeadingSpaces);

            block.Append(' ', 4);
            Assert.AreEqual(3, line.LeadingSpaces); // 3 leading spaces on 3 blocks

            block.Append('!', 4);
            Assert.AreEqual(3, line.LeadingSpaces); // content on 3rd block

            block.Append(' ', 4);
            Assert.AreEqual(3, line.LeadingSpaces); // new spaces on block with content doesn't add leading spaces to line

            block = new HtmlBlock();
            line.AddBlock(block);
            Assert.AreEqual(3, line.LeadingSpaces); // new block doesn't add leading spaces to line

            block.Append(' ', 4);
            Assert.AreEqual(3, line.LeadingSpaces); // new spaces on new block doesn't add leading spaces to line
        }

        #endregion // LeadingSpaces

        #endregion // Methods
    }

}
